package com.wtp.wallpaper.bloomfilter;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import com.wtp.wallpaper.mapper.PictureMapper;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.Charset;
import java.util.List;

@Service
public class BloomFilterService {
    private  volatile BloomFilter<String> bloomFilter;
    @Autowired
    private PictureMapper pictureMapper;

    @PostConstruct
    public void initBloomFilter() {
/*        // 预期数据量 100000，误判率 1%
        bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 10000 + pictureMapper.selectCount(new QueryWrapper<>()), 0.01);

        // 从数据库加载所有哈希值
        List<String> existingHashes = pictureMapper.findAllMd5Hashes();
        existingHashes.forEach(bloomFilter::put);*/

        /*    // 预期数据量 100000，误判率 1%
        //bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 10000 + pictureMapper.selectCount(new QueryWrapper<>()), 0.01);
        bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 10000 + tabsMapper.selectCount(new QueryWrapper<>()), 0.01);
        Long currentTime = System.currentTimeMillis();
        // 从数据库加载所有哈希值
        List<Tabs> existingHashes = tabsMapper.selectList(new QueryWrapper<>());
        existingHashes.forEach(tabs -> {
            bloomFilter.put(tabs.getTabName());
        });
        Long endTime = System.currentTimeMillis();
        System.out.println("用时:" + (endTime - currentTime) + "ms");    // 预期数据量 100000，误判率 1%
        //bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 10000 + pictureMapper.selectCount(new QueryWrapper<>()), 0.01);
        bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 10000 + tabsMapper.selectCount(new QueryWrapper<>()), 0.01);
        Long currentTime = System.currentTimeMillis();
        // 从数据库加载所有哈希值
        List<Tabs> existingHashes = tabsMapper.selectList(new QueryWrapper<>());
        existingHashes.forEach(tabs -> {
            bloomFilter.put(tabs.getTabName());
        });
        Long endTime = System.currentTimeMillis();
        System.out.println("用时:" + (endTime - currentTime) + "ms");*/
        rebuildBloomFilter();
    }

    public boolean mightContain(String hash) {
        return bloomFilter.mightContain(hash);
    }

    public synchronized void addToBloomFilter(String hash) {
        bloomFilter.put(hash); // 同步写操作
    }

    public synchronized void rebuildBloomFilter() {
        // 从数据库加载最新数据
        long expectedInsertions = 10000 + pictureMapper.selectCount(new QueryWrapper<>());
        BloomFilter<String> newFilter = BloomFilter.create(
                Funnels.stringFunnel(Charset.defaultCharset()),
                expectedInsertions,
                0.01
        );
        List<String> existingHashes = pictureMapper.findAllMd5Hashes();
        existingHashes.forEach(newFilter::put);

        // 替换旧实例（volatile 写保证可见性）
        bloomFilter = newFilter;
    }
}